﻿#pragma once
#include "zyObject.hpp"


namespace DarkMoonUI {
    class zyBase {
    protected:
        zyObject* m_obj;

    public:
        zyBase() : m_obj(zyObject::Create()) {
            m_obj->setWndProc(zyBase_WndProc);
            m_obj->setChildWndProc(zyBase_ChildWndProc);
            m_obj->setDestroy(zyBase_Destroy);
        }
        ~zyBase() { m_obj->release(); }

        zyObject* getObject(BOOL bAddRef = FALSE) const {
            if (bAddRef) m_obj->addRef();
            return m_obj;
        }

        zyObject* 取对象(BOOL 添加引用 = FALSE) const { return getObject(添加引用); }

        BOOL setObject(zyObject* newObj, BOOL bAddRef = TRUE) {
            if (newObj == NULL || !m_obj->checkSelf()) return FALSE;
            if (newObj == m_obj) return TRUE;
            m_obj->release();
            m_obj = newObj;
            if (bAddRef) m_obj->addRef();
            return TRUE;
        }

        BOOL 置对象(zyObject* 新对象, BOOL 添加引用 = TRUE) { return setObject(新对象, 添加引用); }

        BOOL setHwnd(HWND hwnd) {
            if (hwnd && IsWindow(hwnd)) {
                auto newObj = zyEnv::getInstance().getWndObject(hwnd);
                return setObject(newObj);
            }
            return FALSE;
        }

        //根据窗口句柄获取类对象，如果此窗口句柄之前不是由本模块创建或绑定，则返回假
        BOOL 置窗口句柄(HWND 窗口句柄) { return setHwnd(窗口句柄); }

        HWND getHwnd() const { return (HWND)m_obj->getPtrData(L"hWnd"); }

        HWND 取窗口句柄() const { return getHwnd(); }

        int getBorder() const { return (int)(LONG_PTR)m_obj->getPtrData(L"Border"); }

        void setBorder(int border) { m_obj->setPtrData(L"Border", (void*)(LONG_PTR)border); }

        BOOL hasBorder() const { return m_obj->hasPtrData(L"Border"); }

        BOOL HasMember(const std::wstring& name) { return m_obj->hasPtrData(name);}
        //RECT* rc = GetMember<RECT>(L"RECT");
        //template <typename T>
        //T* GetMember(const std::wstring& name)const { return (T*)m_obj->getPtrData(name); }
        LONG_PTR GetMember(const std::wstring& name) const { return (LONG_PTR)m_obj->getPtrData(name); }
        
        //template <typename T>
        //T* SetMember(const std::wstring& name,T* border)const { return (m_obj->setPtrData(name,border); }
        void SetMember(const std::wstring& name,LONG_PTR border) { m_obj->setPtrData(name, (void*)border); }
        
        void SetRegEvent(const std::wstring& name, TRegEvent* pRegEvent) { m_obj->setRegEvent(name, pRegEvent); }

        TRegEvent* GetRegEvent(const std::wstring& name) const { return m_obj->getRegEvent(name); }
    protected:
        static void zyBase_Destroy(zyObject* obj);
        static void zyBase_OnNCDestroy(zyObject* obj);
        static LRESULT CALLBACK zyBase_WndProc(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* bHandled);
        static LRESULT CALLBACK zyBase_ChildWndProc(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* bHandled);
        static int GetFunKeyState();
    private:
        

        static BOOL SysHotKeyHandler(HWND hWnd, const std::wstring& className, wchar_t wchr);
    };

}

// class zyBase {
// public:
//     zyBase() : m_obj(new zyObject()) {}

//     zyObject* getObject() const { return m_obj; }
//     void setObject(zyObject* obj) {
//         m_obj->release();
//         m_obj = obj;
//         m_obj->addRef();
//     }

//     std::wstring getName() const { return m_obj->getStringData(L"Name"); }

//     void setName(const std::wstring& name) { m_obj->setStringData(L"Name", name); }

//     std::wstring getType() const { return m_obj->getStringData(L"Type"); }

//     void setType(const std::wstring& type) { m_obj->setStringData(L"Type", type); }

//     void setHwnd(HWND hwnd) { m_obj->setPtrData(L"Hwnd", hwnd); }

//     HWND getHwnd() const { return (HWND)m_obj->getPtrData(L"Hwnd"); }

//     LONG_PTR getBorder() const { return (LONG_PTR)m_obj->getPtrData(L"Border"); }

//     void setBorder(LONG_PTR border) { m_obj->setPtrData(L"Border", (void*)border); }

//     bool hasBorder() const { return m_obj->hasPtrData(L"Border"); }

// private:
//     zyObject* m_obj;
// };